<?php
/**
 *
 */
require_once 'Zend/Sql/Adapter/Standard/Statement/Abstract.php';

class Zend_Sql_Adapter_Standard_Statement_Select
	extends Zend_Sql_Adapter_Standard_Statement_Abstract
{
	const COMMAND = 'SELECT';

	/**
	 * select expression
	 * @var Zend_Sql_Statement_Expression_List<Zend_Sql_Statement_Expression_Identifier>
	 */
	protected $select;
	/**
	 * from expression
	 * @var Zend_Sql_Adapter_Standard_Expression_Clause_From|Zend_Sql_Adapter_Standard_Statement_Select
	 */
	protected $from;
	
	/**
	 * where expression
	 * @var Zend_Sql_Statement_Clause_Where
	 */
	protected $where;
	/**
	 * order by expression
	 * @var Zend_Sql_Statement_Clause_OrderBy
	 */
	protected $order;
	/**
	 * limit_expr
	 * @var Zend_Sql_Statement_Clause_Limit
	 */
	protected $limit;

	function __construct($options=null) {
		$this->command = self::COMMAND;
		$this->reset();
	}
	function __destruct() {
		$this->reset();
	}
	public function reset() {
		$this->use = array();
		return $this;
	}
	
	/**
	 * @param Zend_Sql_Adapter_Standard_Expression_Abstract $expression
	 */
	public function setSelect($expressions) {
		if ($expressions instanceof Zend_Sql_Adapter_Standard_Expression_List) {
			$this->select = $expressions;
			return $this;
		}
		
		if (!is_array($expressions)) {
			throw new Zend_Sql_Exception('Bad type parameter');
		}
		
		$order = array( '*', '/', '-', '+', 'and', 'or', '=');
		$this->select = new Zend_Sql_Adapter_Standard_Expression_List();
		foreach ($expressions as $expression) {
			if (!empty($expression['ops'])) {
				foreach ($order as $op) {
					$expression = $this->compilePrecedence($expression, $op);
				}
				$expression = $expression['args'][0];
			} else {
				$expression = Zend_Sql_Adapter_Standard_Expression::factory($expression['args'][0]['type']);
				$expression->setValue($expression['args'][0]['value']);
			}
			$this->select[] = $expression;
		}
		return $this;
	}
	
	/**
	 * Refactor & Compile an operation
	 */
	protected function compilePrecedence($expression, $op) {
		$keys = array_keys($expression['ops'], $op);// *, +, ...
		if(!count($keys)) {
			return $expression;
		}
		$key = current($keys);
		$logical = Zend_Sql_Adapter_Standard_Expression::factory($op);
			$operand = $expression['args'][$key];
			if (is_array($operand)) {
				$operand = Zend_Sql_Adapter_Standard_Expression::factory($expression['args'][$key]['type']);
				$operand->setValue($expression['args'][$key]['value']);
			}
			$logical->setOperand($operand);
		
			$argument = $expression['args'][$key+1];
			if (is_array($argument)) {
				$argument = Zend_Sql_Adapter_Standard_Expression::factory($expression['args'][$key+1]['type']);
				$argument->setValue($expression['args'][$key+1]['value']);
			}
			$logical->setArgument($argument);
		
		$expression['args'][$key+1] = $logical;
		unset($expression['args'][$key]);
		unset($expression['ops'][$key]);
		// reindex
		$expression['args'] = array_values($expression['args']);
		$expression['ops']  = array_values($expression['ops']);
		
		return $this->compilePrecedence($expression, $op);
	}
	
	/**
	 * @param Zend_Sql_Adapter_Standard_Expression_Clause_From|Zend_Sql_Adapter_ $clause
	 */
	public function from($clause, $columns=null) {
		print_r($clause);
		return $this;
	}
	
	public function joinLeft($clause, $on, $columns) {
		$this->use[] = $clause;
		return $this;
	}
	
	public function toString() {
		// $visitorStatementSelect->toString();
		
		// $visitor->statementSelect($this);
		// $compile->statementSelect($this);
		$from = $this->getFrom();
		$table_identifier = $from->toString();
		if ($from instanceof Zend_Sql_Adapter_Standard_Statement_Select) {
			$table_identifier = ' (' . $table_identifier . ') ';
		}
		return 'SELECT * FROM ' . $table_identifier . ' WHERE 1';
	}
}
